package org.custom.spring.boot.transaction.service.transactional;

import org.custom.spring.boot.transaction.async.AsyncCall;
import org.custom.spring.boot.transaction.entity.Transaction;
import org.custom.spring.boot.transaction.mapper.TransactionMapper;
import org.custom.spring.boot.transaction.service.propagation.RequiresNewService;
import org.custom.spring.boot.transaction.utils.ValidUtil;
import org.custom.spring.boot.useless.Result;
import org.springframework.context.annotation.Description;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * 非事务方法调用
 *
 * @author LiKun
 * @date 2021/9/17 10:08
 */
@Service
public class TransactionalService {
    @Resource
    private AsyncCall asyncCall;
    @Resource
    private AssistService assistService;
    @Resource
    private TransactionMapper transactionMapper;
    @Resource
    private RequiresNewService requiresNewService;

    @Result("A&&b回滚(1)")
    @Description("A内部调用b(抛出异常)")
    @Transactional
    public int callTransactionInner(String data1, String data2) {
        transactionMapper.insert(Transaction.getInstance(data1));
        try {
            this.innerException(data2);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ValidUtil.byZero();
    }

    @Result("A&&B回滚(1)")
    @Description("A(抛出异常)外部调用b/B")
    @Transactional
    public int callExceptionTransaction(String data1, String data2) {
        transactionMapper.insert(Transaction.getInstance(data1));
        assistService.withoutTransaction(data2);
//        assistService.withTransaction(data2);
        return ValidUtil.byZero();
    }

    @Result("A&&B回滚(1)")
    @Description("A外部调用b/B(抛出异常)")
    @Transactional
    public int callTransactionException(String data1, String data2) {
        transactionMapper.insert(Transaction.getInstance(data1));
//        return assistService.withoutTransactionException(data2);
        return assistService.withTransactionException(data2);
    }

    @Result("A&&B不会/会回滚(1)")
    @Description("A(捕获异常)外部调用b/B(抛出异常)")
    @Transactional
    public int callCatchTransactionException(String data1, String data2) {
        transactionMapper.insert(Transaction.getInstance(data1));
        try {
//            assistService.withoutTransactionException(data2);
            assistService.withTransactionException(data2);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("继续执行之后的代码");
        return 99;
    }

    @Result("A&&B回滚(2)")
    @Description("A外部调用B(NEW&&抛出异常)")
    @Transactional
    public int newTransactionException(String data1, String data2) {
        transactionMapper.insert(Transaction.getInstance(data1));
        return requiresNewService.transactionException(data2);
    }

    @Result("A回滚(2)")
    @Description("A(抛出异常)外部调用B(NEW)")
    @Transactional
    public int newExceptionTransaction(String data1, String data2) {
        transactionMapper.insert(Transaction.getInstance(data1));
        requiresNewService.transaction(data2);
        return ValidUtil.byZero();
    }

    @Result("A回滚(2)")
    @Description("A(抛出异常)外部调用B(NEW)")
    @Transactional
    public int newCatchTransactionException(String data1, String data2) {
        transactionMapper.insert(Transaction.getInstance(data1));
        try {
            requiresNewService.transactionException(data2);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 99;
    }

    @Result("B回滚(1)")
    @Description("a异步调用B(抛出异常)")
    @Transactional
    public int asyncCallTransactionException(String data1, String data2) throws Exception {
        transactionMapper.insert(Transaction.getInstance(data1));
        return asyncCall.transactionException(data2).get();
    }


    private int innerException(String data) {
        transactionMapper.insert(Transaction.getInstance(data));
        return ValidUtil.byZero();
    }
}
